package com.yiyi.credit.manage.sso.service.inner;

import com.yiyi.credit.manage.sso.cache.RedisManager;
import com.yiyi.credit.manage.sso.common.Constant;
import com.yiyi.credit.manage.sso.common.exception.ResponseCode;
import com.yiyi.credit.manage.sso.common.exception.ServiceException;
import com.yiyi.credit.manage.sso.mapper.SysRoleResourceMapper;
import com.yiyi.credit.manage.sso.model.dto.SysResourceDto;
import com.yiyi.credit.manage.sso.model.entity.SysResource;
import com.yiyi.credit.manage.sso.model.entity.SysRoleResource;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class SysRoleResourceServiceImpl implements SysRoleResourceService {

    @Autowired
    SysRoleResourceMapper sysRoleResourceMapper;

    @Autowired
    SysResourceService sysResourceService;

    @Autowired
    RedisManager redisManager;



    @Transactional(rollbackFor = Exception.class)
    @Override
    public void assignSysRoleResource(Long sysInfoId, Long sysRoleId, String ids) throws ServiceException {

        //获取变化的资源信息
        Map<String, String> map = getChangeSelectResource(sysInfoId, sysRoleId, ids);
        //需要删除的资源
        String deleteIds = map.get(Constant.DELETE_IDS);
        //需要增加的资源
        String addIds = map.get(Constant.ADD_IDS);

        //删除减少的资源信息
        if (StringUtils.isNotBlank(deleteIds)) {
            String[] deleteIdList = deleteIds.split(Constant.SPLIT_ATTR);
            for (String deleteId : deleteIdList) {
                //删除角色原有资源信息
                Example example = new Example(SysRoleResource.class);
                example.createCriteria().andEqualTo("sysRoleId", sysRoleId).andEqualTo("sysInfoId", sysInfoId)
                    .andEqualTo("sysResourceId", Long.parseLong(deleteId));
                sysRoleResourceMapper.deleteByExample(example);
            }
        }

        //添加对应角色的资源信息
        if (StringUtils.isNotBlank(addIds)) {
            String[] idList = addIds.split(Constant.SPLIT_ATTR);
            if (idList.length == Constant.INT_ZERO) {
                throw new ServiceException(ResponseCode.RESOURCE_NOT_FUND);
            }
            //SysResource sysResource;
            //SysRoleResource sysRoleResource = null;
            List<SysRoleResource> sysRoleResourceList = new ArrayList<>();
            for (String id : idList) {
                //查询资源
                SysResource sysResource = sysResourceService.getSysResourceById(Long.parseLong(id));
                if (null != sysResource) {
                    SysRoleResource sysRoleResource = new SysRoleResource();
                    sysRoleResource.setSysInfoId(sysInfoId);
                    sysRoleResource.setSysRoleId(sysRoleId);
                    sysRoleResource.setSysResourceId(sysResource.getId());
                    sysRoleResource.setPid(sysResource.getParentId());
                    sysRoleResourceList.add(sysRoleResource);
                }
            }
            if (sysRoleResourceList.size() > Constant.INT_ZERO) {
                //插入
                sysRoleResourceMapper.insertList(sysRoleResourceList);
            }
        }
    }


    private Map<String, String> getChangeSelectResource(Long sysInfoId, Long sysRoleId, String ids) throws ServiceException {
        Map<String, String> map = new HashMap<>();
        //修改之前的资源id
        String oldIds = "";
        List<SysRoleResource> oldListResource = getSysRoleResource(sysInfoId, sysRoleId);
        if (null != oldListResource && oldListResource.size() > Constant.INT_ZERO) {
            StringBuilder stringBuilder = new StringBuilder();
            for (SysRoleResource sysRoleResource : oldListResource) {
                stringBuilder.append(sysRoleResource.getSysResourceId()).append(Constant.SPLIT_ATTR);
                //oldIds += sysRoleResource.getSysResourceId() + Constant.SPLIT_ATTR;
            }
            stringBuilder.setLength(stringBuilder.length() - Constant.INT_ONE);
            oldIds = stringBuilder.toString();
        }

        //需要删除的资源
        String deleteIds = "";
        //需要增加的资源
        String addIds = "";

        //如果oldIds为空
        if (StringUtils.isBlank(oldIds)) {
            map.put(Constant.DELETE_IDS, deleteIds);
            map.put(Constant.ADD_IDS, ids);
            return map;
        }

        //如果ids为空
        if (StringUtils.isBlank(ids)) {
            map.put(Constant.DELETE_IDS, oldIds);
            map.put(Constant.ADD_IDS, addIds);
            return map;
        }

        //oldIds和ids都不为空时
        String[] oldList = oldIds.split(Constant.SPLIT_ATTR);
        String[] newList = ids.split(Constant.SPLIT_ATTR);
        //获取需要删除的资源id
        deleteIds = getChangeIds(oldList, newList);
        //获取需要新增的资源id
        addIds = getChangeIds(newList, oldList);
        map.put(Constant.DELETE_IDS, deleteIds);
        map.put(Constant.ADD_IDS, addIds);
        return map;
    }


    private String getChangeIds(String[] outList, String[] insideList) {

        StringBuilder stringBuilder = new StringBuilder("");
        for (String out : outList) {
            boolean flag = true;
            for (String inside : insideList) {
                if (out.equals(inside)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                stringBuilder.append(out).append(Constant.SPLIT_ATTR);
            }
        }
        if (StringUtils.isNotBlank(stringBuilder.toString())) {
            stringBuilder.setLength(stringBuilder.length() - Constant.INT_ONE);
        }
        return stringBuilder.toString();
    }


    @Override
    public List<SysRoleResource> getSysRoleResource(Long sysInfoId, Long sysRoleId) throws ServiceException {
        Example example = new Example(SysRoleResource.class);
        example.createCriteria().andEqualTo("sysInfoId", sysInfoId).andEqualTo("sysRoleId", sysRoleId);
        return sysRoleResourceMapper.selectByExample(example);
    }


    @Override
    public List<SysResourceDto> getSysRoleResourceTree(Long sysInfoId, Long sysRoleId) throws ServiceException {
        //获取系统全部资源
        List<SysResourceDto> sysResourceList = getSysResourceBySysId(sysInfoId);
        //获取当前角色具有的资源
        List<SysRoleResource> sysRoleResourceList = getSysRoleResource(sysInfoId, sysRoleId);
        if (null != sysResourceList && sysResourceList.size() > Constant.INT_ZERO
            && null != sysRoleResourceList && sysRoleResourceList.size() > Constant.INT_ZERO) {
            for (SysRoleResource sysRoleResource : sysRoleResourceList) {
                for (SysResourceDto sysResourceDto : sysResourceList) {
                    //该角色有该权限资源设置check
                    if (sysRoleResource.getSysResourceId().equals(sysResourceDto.getId())
                        && sysRoleResource.getPid().equals(sysResourceDto.getParentId())) {
                        sysResourceDto.setChecked(true);
                    }
                }
            }
        }
        return sysResourceList;
    }


    @Override
    public List<Map<String, Object>> getSysRoleColumnsTree(Long sysInfoId, Long sysRoleId) throws ServiceException {

        return sysRoleResourceMapper.getSysRoleColumnsTree(sysInfoId, sysRoleId);
    }


    @Override
    public int addSysRoleResource(SysRoleResource sysRoleResource) throws ServiceException {

        return sysRoleResourceMapper.insertSelective(sysRoleResource);
    }

    @Override
    public int updateSysRoleResource(SysRoleResource sysRoleResource) throws ServiceException {

        return sysRoleResourceMapper.  updateByPrimaryKeySelective(sysRoleResource);
    }


    @Override
    public void deleteSysRoleResourceByRoleId(Long sysRoleId) throws ServiceException {
        Example example = new Example(SysRoleResource.class);
        example.createCriteria().andEqualTo("sysRoleId", sysRoleId);
        sysRoleResourceMapper.deleteByExample(example);
    }


    @Override
    public void deleteSysRoleResourceByResourceId(Long resourceId) throws ServiceException {
        Example example = new Example(SysRoleResource.class);
        example.createCriteria().andEqualTo("sysResourceId", resourceId);
        sysRoleResourceMapper.deleteByExample(example);
    }


    private List<SysResourceDto> getSysResourceBySysId(Long sysInfoId) throws ServiceException {
        List<SysResourceDto> resultList = new ArrayList<>();
        List<SysResource> list = sysResourceService.getSysResourceBySysId(sysInfoId);
        if (null != list && list.size() > Constant.INT_ZERO) {
            SysResourceDto sysResourceDto = null;
            for (SysResource sysResource : list) {
                sysResourceDto = new SysResourceDto();
                sysResourceDto.setId(sysResource.getId());
                sysResourceDto.setName(sysResource.getName());
                sysResourceDto.setParentId(sysResource.getParentId());
                resultList.add(sysResourceDto);
            }
        }
        return resultList;
    }
}
